package com.siss.tenancy.util;



import com.siss.tenancy.annotation.PropertyMsg;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * <p>
 * 类名: BeanChangeUtil
 * </p>
 * <p>
 * 描述:TODO
 * </p>
 * <p>
 * 创建人: liyp
 * </p>
 * <p>
 * 创建时间: 2020/5/28 14:00
 * </p>
 * <p>
 * 
 * @version 2.0
 * </p>
 * <p>
 * 修改内容: ......
 * </p>
 * <p>
 * 修改说明: ......
 * </p>
 * <p>
 * 修改时间: ......
 * </p>
 * <p>
 * 修改人: ......
 * </p>
 * <p>
 * 每次修改，请增加上述修改信息说明</>
 */
public class BeanChangeUtil<T> {

    public List<Map<String, String>> contrastObj(List<T> oldBean, List<T> newBean, Class<T> clazz) {
        List<Map<String, String>> result = new ArrayList<>();
        for (T t : oldBean) {
            for (T t1 : newBean) {
                // 获取类型及字段属性
                Field[] fields = clazz.getDeclaredFields();
                List<Map<String, String>> returnValue = jdk8OrAfter(fields, t, t1, clazz);
                if (null != returnValue) {
                    result.addAll(returnValue);
                    break;
                }
            }
        }
        return result;
    }

    public List<Map<String, String>> jdk8OrAfter(Field[] fields, T pojo1, T pojo2, Class clazz) {
        List<Map<String, String>> listMap = new ArrayList<>();
        String topicId = "";
        boolean hasId = false;
        for (Field field : fields) {
            if (field.getName().equals("id")) {
                hasId = true;
                try {
                    PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                    // 获取对应属性值
                    Method getMethod = pd.getReadMethod();
                    Object o1 = getMethod.invoke(pojo1);
                    Object o2 = getMethod.invoke(pojo2);
                    if (o1 == null || o2 == null) {
                        return null;
                    }
                    if (!o1.toString().equals(o2.toString())) {
                        // id不一致
                        return null;
                    }
                    topicId = o2.toString();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        if (!hasId) {
            throw new IllegalThreadStateException("没有id属性，不能比较");
        }
        final int[] i = { 1 };
        Arrays.asList(fields).forEach(f -> {
            if (f.isAnnotationPresent(PropertyMsg.class)) {
                try {
                    Map<String, String> map = new HashMap<>();
                    PropertyDescriptor pd = new PropertyDescriptor(f.getName(), clazz);
                    // 获取对应属性值
                    Method getMethod = pd.getReadMethod();
                    Object o1 = getMethod.invoke(pojo1);
                    Object o2 = getMethod.invoke(pojo2);
                    if (null != o1 && o1.toString().indexOf(".") != -1) {
                        if (null != o2 && o2.toString().indexOf(".") == -1) {
                            o2 += ".0000";
                        } else if (null != o2) {
                            int dotIndex = o2.toString().indexOf(".");
                            String res = o2.toString().substring(dotIndex + 1);
                            if (res.length() == 1) {
                                o2 += "000";
                            }
                        }
                    }
                    // 如果是之前为null，现在不是null，之前不是null，现在是null的情况，这种是允许的，vo已经限制了更新不为空的字段
                    if (o1 == null && o2 != null) {
                        map.put("title", f.getAnnotation(PropertyMsg.class).value());
                        map.put("oldValue", "");
                        map.put("newValue", o2.toString());
                        if (o2 instanceof Date) {
                            map.put("newValue", ParserDate.getFDay((Date) o2, "yyyy-MM-dd HH:mm:ss"));
                        }
                        listMap.add(map);
                    } else if (o1 != null && o2 == null) {
                        map.put("title", f.getAnnotation(PropertyMsg.class).value());
                        map.put("oldValue", o1.toString());
                        if (o1 instanceof Date) {
                            map.put("oldValue", ParserDate.getFDay((Date) o1, "yyyy-MM-dd HH:mm:ss"));
                        }
                        map.put("newValue", "");
                        listMap.add(map);
                    } else if (null != o1 && null != o2) {
                        if (!o1.toString().equals(o2.toString())) {
                            // 记录修改的日志
                            map.put("title", f.getAnnotation(PropertyMsg.class).value());
                            map.put("oldValue", o1.toString());
                            map.put("newValue", o2.toString());
                            if (o1 instanceof Date) {
                                map.put("oldValue", ParserDate.getFDay((Date) o1, "yyyy-MM-dd HH:mm:ss"));
                                map.put("newValue", ParserDate.getFDay((Date) o2, "yyyy-MM-dd HH:mm:ss"));
                            }
                            listMap.add(map);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        for (Map<String, String> stringStringMap : listMap) {
            stringStringMap.put("topicId", topicId);
        }
        return listMap;
    }

}
